home *** CD-ROM | disk | FTP | other *** search
- /**
- * Copyright (c) 1985 Sun Microsystems, Inc.
- * Copyright (c) 1980 The Regents of the University of California.
- * Copyright (c) 1976 Board of Trustees of the University of Illinois.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted provided
- * that the above copyright notice and this paragraph are duplicated in all
- * such forms and that any documentation, advertising materials, and other
- * materials related to such distribution and use acknowledge that the
- * software was developed by the University of California, Berkeley, the
- * University of Illinois, Urbana, and Sun Microsystems, Inc. The name of
- * either University or Sun Microsystems may not be used to endorse or
- * promote products derived from this software without specific prior written
- * permission. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
- * OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- #include "globals.h"
-
- #ifndef lint
- # ifndef ANSIC
- static char sccsid[] = "@(#)args.c 6.0 (Berkeley) 92/06/15";
- # endif /* ANSIC */
- #endif /* not lint */
-
- /* Argument scanning and profile reading code. Default parameters are set
- * here as well. */
-
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
-
- #ifdef ANSIC
- static void scan_profile(FILE *);
- #endif /* ANSIC */
-
- /* Profile types */
- #define PRO_SPECIAL 1 /* special case */
- #define PRO_BOOL 2 /* Boolean */
- #define PRO_INT 3 /* integer */
- #define PRO_FONT 4 /* troff font */
-
- /* Profile specials for Booleans. Booleans can be set to USE or IGNORE. USE
- * reads the value, IGNORE ignores the value and keeps the default */
- #define USE 0 /* turn it off */
-
- /* Profile specials for specials */
- #define IGNORE 1 /* ignore it */
- #define KEY 4 /* type (keyword) */
-
- char *option_source = "?";
-
- /* N.B.: option names can't start with n */
- struct pro {
- char *p_name; /* name, e.g. -br, -cli */
- int p_type; /* type (int, bool, special) */
- int p_default; /* the default value (if int) */
- int p_special; /* depends on type */
- int *p_obj; /* the associated variable */
- } pro[] = {
- {
- "+", PRO_BOOL, true, USE, &cplus
- },
- {
- "T", PRO_SPECIAL, 0, KEY, 0
- },
- {
- "bacc", PRO_BOOL, false, USE, &blanklines_around_conditional_compilation
- },
- {
- "bad", PRO_BOOL, false, USE, &blanklines_after_declarations
- },
- {
- "badp", PRO_BOOL, false, USE, &blanklines_after_declarations_at_proctop
- },
- {
- "bap", PRO_BOOL, false, USE, &blanklines_after_procs
- },
- {
- "bbb", PRO_BOOL, false, USE, &blanklines_before_blockcomments
- },
- {
- "bc", PRO_BOOL, false, USE, &ps.leave_comma
- },
- {
- "br", PRO_BOOL, true, USE, &btype_2
- },
- {
- "brr", PRO_BOOL, false, USE, &btype_3
- },
- {
- "bs", PRO_BOOL, false, USE, &Bill_Shannon
- },
- {
- "c", PRO_INT, 33, 0, &ps.com_ind
- },
- {
- "cci", PRO_INT, 4, 0, &ps.case_code_indent
- },
- {
- "cd", PRO_INT, 0, 0, &ps.decl_com_ind
- },
- {
- "cdb", PRO_BOOL, false, USE, &comment_delimiter_on_blankline
- },
- {
- "ce", PRO_BOOL, true, USE, &cuddle_else
- },
- {
- "ci", PRO_INT, 0, 0, &continuation_indent
- },
- {
- "cli", PRO_INT, 0, 0, &ps.case_indent
- },
- {
- "cp", PRO_INT, 17, 0, &ps.else_endif_col
- },
- {
- "d", PRO_INT, 0, 0, &ps.unindent_displace
- },
- {
- "di", PRO_INT, 16, 0, &ps.decl_indent
- },
- {
- "dj", PRO_BOOL, false, USE, &ps.ljust_decl
- },
- {
- "eei", PRO_BOOL, false, USE, &extra_expression_indent
- },
- {
- "ei", PRO_BOOL, true, USE, &ps.else_if
- },
- {
- "fb", PRO_FONT, 0, 0, (int *) &bodyf
- },
- {
- "fbc", PRO_FONT, 0, 0, (int *) &blkcomf
- },
- {
- "fbx", PRO_FONT, 0, 0, (int *) &boxcomf
- },
- {
- "fc", PRO_FONT, 0, 0, (int *) &scomf
- },
- {
- "fc1", PRO_BOOL, false, USE, &format_col1_comments
- },
- {
- "fk", PRO_FONT, 0, 0, (int *) &keywordf
- },
- {
- "fs", PRO_FONT, 0, 0, (int *) &stringf
- },
- {
- "i", PRO_INT, 4, 0, &ps.ind_size
- },
- {
- "ip", PRO_BOOL, true, USE, &ps.indent_parameters
- },
- {
- "l", PRO_INT, 78, 0, &max_col
- },
- {
- "lc", PRO_INT, 0, 0, &block_comment_max_col
- },
- {
- "ldefs", PRO_BOOL, false, USE, &list_defines
- },
- {
- "lp", PRO_BOOL, true, USE, &lineup_to_parens
- },
- {
- "pcs", PRO_BOOL, false, USE, &proc_calls_space
- },
- {
- "pro", PRO_BOOL, true, USE, &useProfile
- },
- {
- "prs", PRO_BOOL, false, USE, &parens_space
- },
- {
- "ps", PRO_BOOL, false, USE, &pointer_as_binop
- },
- {
- "psl", PRO_BOOL, false, USE, &procnames_start_line
- },
- {
- "sc", PRO_BOOL, true, USE, &star_comment_cont
- },
- {
- "sob", PRO_BOOL, false, USE, &swallow_optional_blanklines
- },
- {
- "st", PRO_BOOL, false, USE, &useStdio
- },
- {
- "tabs", PRO_INT, 8, 0, &tabsize
- },
- {
- "tabu", PRO_BOOL, false, 0, &usetabs
- },
- {
- "troff", PRO_BOOL, false, USE, &troff
- },
- {
- "v", PRO_BOOL, false, USE, &verbose
- },
- {
- 0, 0, 0, 0, 0
- },
- /* whew! */
- };
-
- /**
- * NAME: void set_profile(void)
- *
- * FUNCTION: set_profile reads $HOME/indent.pro and ./indent.pro and handles
- * arguments given in these files.
- *
- * ALGORITHM:
- *
- * PARAMETERS: Reads the environment.
- *
- * RETURNS:
- *
- * GLOBALS READ:
- *
- * GLOBALS CHANGED:
- *
- * CALLED BY:
- *
- * HISTORY: Peter Hadfield 09-03-93 Removed the '.' (UNIX hidden file marker)
- * from indent.pro to allow the same code to be used for DOS and UNIX.
- *
- * Added display of profile file path for verbose option.
- * Fixed problem with (null) being written into fname if getenv() returns NULL.
- *
- * Added reading of a profile file with the same path and name as the binary
- * (but with a .pro extension).*/
-
- #ifdef ANSIC
- void set_profile(char *bin_name)
- #else /* ANSIC */
- set_profile(bin_name)
- char *bin_name;
- #endif /* ANSIC */
- {
- FILE *stream;
- char fname[BUFSIZ] = "";
- char *env_ptr = NULL;
- static char prof[] = "indent.pro"; /* this is no longer a UNIX
- * hidden file so the DOS port
- * can use the same code */
- strcpy(fname, bin_name);
- if (fname[strlen(fname) - 4] == '.') /* assume its a DOS file name */
- (fname[strlen(fname) - 4] = '\0'); /* remove the extension */
- strcat(fname, ".pro");
- if ((stream = fopen(option_source = fname, "r")) != NULL) {
- if ((verbose) || (show_options))
- fprintf(stderr, "Reading profile file: %s", fname);
- scan_profile(stream);
- (void) fclose(stream);
- }
- env_ptr = getenv("HOME");
- if (env_ptr != NULL) {
- sprintf(fname, "%s/%s", env_ptr, prof);
- if ((stream = fopen(option_source = fname, "r")) != NULL) {
- if ((verbose) || (show_options))
- fprintf(stderr, "\nReading profile file: %s", fname);
- scan_profile(stream);
- (void) fclose(stream);
- }
- }
- sprintf(fname, "%s", prof);
- if ((stream = fopen(option_source = fname, "r")) != NULL) {
- if ((verbose) || (show_options))
- fprintf(stderr, "Reading profile file: %s", fname);
- scan_profile(stream);
- (void) fclose(stream);
- }
- option_source = "Command line";
- }
-
- /** NAME:
- *
- * FUNCTION:
- *
- * ALGORITHM:
- *
- * PARAMETERS:
- *
- * RETURNS:
- *
- * GLOBALS READ:
- *
- * GLOBALS CHANGED:
- *
- * CALLED BY:
- *
- * HISTORY:
- */
- #ifdef ANSIC
- static void scan_profile(FILE * f)
- #else /* ANSIC */
- scan_profile(f)
- FILE *f;
- #endif /* ANSIC */
- {
- int i;
- char *p = NULL;
- char buf[BUFSIZ] = "";
-
- while (1) {
- for (p = buf; (i = getc(f)) != EOF && (*p = (char) i) > ' '; ++p);
- if (p != buf) {
- *p++ = 0;
- if ((verbose) || (show_options))
- fprintf(stderr, " %s", buf);
- set_option(buf);
- } else if (i == EOF) {
- if ((verbose) || (show_options))
- fprintf(stderr, "\n\n", buf);
- return;
- }
- }
- }
-
- /** NAME:
- *
- * FUNCTION: Set the defaults.
- *
- * ALGORITHM:
- *
- * PARAMETERS:
- *
- * RETURNS:
- *
- * GLOBALS READ:
- *
- * GLOBALS CHANGED:
- *
- * CALLED BY:
- *
- * HISTORY:
- *
- */
- #ifdef ANSIC
- void set_defaults(void)
- #else /* ANSIC */
- set_defaults()
- #endif /* ANSIC */
- {
- struct pro *p;
-
- for (p = pro; p->p_name; p++) {
- if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT) {
- *p->p_obj = p->p_default;
- }
- }
- }
-
- /** NAME: list_options()
- *
- * FUNCTION: List the current options.
- *
- * ALGORITHM:
- *
- * PARAMETERS:
- *
- * RETURNS:
- *
- * GLOBALS READ:
- *
- * GLOBALS CHANGED:
- *
- * CALLED BY:
- *
- * HISTORY: */
- #ifdef ANSIC
- void list_options(char *in_name)
- #else /* ANSIC */
- list_options(in_name)
- char *in_name;
- #endif /* ANSIC */
- {
- struct pro *p;
-
- fprintf(stderr, "indent: %-12s", in_name);
-
- for (p = pro; p->p_name; p++) {
- if ((p->p_type == PRO_BOOL) && (*p->p_obj == 1)) {
- fprintf(stderr, " -%s", p->p_name);
- }
- }
- for (p = pro; p->p_name; p++) {
- if (p->p_type == PRO_INT) {
- fprintf(stderr, " -%s:%d", p->p_name, *p->p_obj);
- }
- }
- #if 0
- fprintf(stderr, " fb %s,%c,%d", *bodyf->font, bodyf->allcaps, bodyf->size);
- fprintf(stderr, " fc %s,%c,%d", &scomf->font, scomf->allcaps, scomf->size);
- fprintf(stderr, " fbc %s,%c,%d", &blkcomf->font, blkcomf->allcaps, blkcomf->size);
- fprintf(stderr, " fbx %s,%c,%d", &boxcomf->font, boxcomf->allcaps, boxcomf->size);
- fprintf(stderr, " fs %s,%c,%d", &stringf->font, stringf->allcaps, stringf->size);
- fprintf(stderr, " fk %s,%c,%d", &keywordf->font, keywordf->allcaps, keywordf->size);
- #endif 0
- fprintf(stderr, "\n");
- }
-
-
- /** NAME:
- *
- * FUNCTION:
- *
- * ALGORITHM:
- *
- * PARAMETERS:
- *
- * RETURNS:
- *
- * GLOBALS READ:
- *
- * GLOBALS CHANGED:
- *
- * CALLED BY:
- *
- * HISTORY: (PETER) Added a proper string compare for finding options.
- *
- * Options can now be in any order in the struct.
- *
- * Arguments to options must be separated by a ':', e.g. -l:78
- *
- * If an option name starts with an 'n', assume this is a negated (off) option.
- * This implies that option names can't start with an 'n' */
- #ifdef ANSIC
- void set_option(register char *arg)
- #else /* ANSIC */
- set_option(arg)
- register char *arg;
- #endif /* ANSIC */
- {
- struct pro *p;
- int booleanState;
- int argptr;
- int nameptr;
- char argname[10] = ""; /* maximum length of an option name */
- char optname[10] = ""; /* maximum length of an option
- * argument */
-
- /* skip the leading "-" */
- argptr = 1;
-
- /* if the option name starts with an 'n' record it and skip it. */
- if (arg[argptr] == 'n') {
- argptr++;
- booleanState = 0;
- } else {
- booleanState = 1;
- }
-
- /* record the option name */
- nameptr = 0;
- while ((arg[argptr] != 0) && (arg[argptr] != ':')) {
- argname[nameptr] = arg[argptr];
- nameptr++;
- argptr++;
- }
- argname[nameptr] = 0;
-
- /* record the option argument, if any */
- nameptr = 0;
- if (arg[argptr] == ':') {
- argptr++; /* skip the colon */
- while (arg[argptr] != 0) {
- optname[nameptr] = arg[argptr];
- nameptr++;
- argptr++;
- }
- }
- optname[nameptr] = 0;
-
- for (p = pro; p->p_name; p++) {
- if (strcmp(p->p_name, argname) == 0) {
-
- switch (p->p_type) {
-
- case PRO_BOOL:
- if (p->p_special != IGNORE)
- *p->p_obj = booleanState;
- return;
-
- case PRO_INT:
- if (!isdigit(*optname)) {
- fprintf(stderr, "indent: %s option: \"%s\" requires a parameter\n",
- option_source, argname);
- exit(1);
- }
- *p->p_obj = atoi(optname);
- return;
-
- case PRO_FONT:
- parsefont((struct fstate *) p->p_obj, optname);
- return;
-
- case PRO_SPECIAL:
- switch (p->p_special) {
-
- case IGNORE:
- return;
-
- case KEY:
- if (*optname == 0) {
- fprintf(stderr, "indent: %s option: \"%s\" requires a parameter\n",
- option_source, argname);
- exit(1);
- } else {
- char *str = (char *) malloc(strlen(optname) + 1);
-
- strcpy(str, optname);
- addkey(str, 4);
- return;
- }
- default:
- fprintf(stderr, "indent: set_option: internal error: p_special %d\n", p->p_special);
- exit(1);
- }
- return;
-
- default:
- fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
- p->p_type);
- exit(1);
- }
- }
- }
- fprintf(stderr, "indent: %s: unknown parameter \"%s\"\n", option_source, argname);
- exit(1);
- }
-